package lyl.images;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.*;
import java.io.*;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.swing.*;

import lyl.file.FileUtil;

import com.sun.image.codec.jpeg.*;

/** */
/**
 * @author zsy
 */

public class WaterMark {
    private static List    logoImgs;
    private static List    bgImgs;
    private static boolean flag;

    public static List getBgImgs() {
        return bgImgs;
    }

    /** */
    /**
     * 设置背景水印图片的路径并把图片加载到内存
     * 
     * @param bgImgUrls
     *            背景水印图片的相对路径集合
     * @param path
     *            图片组所在的文件夹路径
     */
    public static void setBgImgs(List bgImgUrls, String path) {
        bgImgs = new ArrayList();
        for (Iterator it = bgImgUrls.iterator(); it.hasNext();) {
            String tem = (String) it.next();
            ImageIcon waterIcon = new ImageIcon(path + tem);
            bgImgs.add(waterIcon.getImage());
        }
    }

    public static List getLogoImgs() {
        return logoImgs;
    }

    /** */
    /**
     * 设置图标水印图片的路径并把图片加载到内存
     * 
     * @param logoImgUrls
     *            图标水印图片的相对路径集合
     * @param path
     *            图片组所在的文件夹路径
     */
    public static void setLogoImgs(List logoImgUrls, String path) {
        logoImgs = new ArrayList();
        for (Iterator it = logoImgUrls.iterator(); it.hasNext();) {
            String tem = (String) it.next();
            ImageIcon waterIcon = new ImageIcon(path + tem);
            logoImgs.add(waterIcon.getImage());
        }
    }

    /** */
    /**
     * 图片中添加图标水印并输出到指定流
     * 
     * @param data
     * @param out
     * @param channel
     * @return
     * @throws Exception
     */
    public static boolean createLogoMark(byte[] data, FileOutputStream out, String channel) throws Exception {
        int i = (int) (logoImgs.size() * Math.random());
        return createMark(data, out, (Image) logoImgs.get(i), true);
    }

    /** */
    /**
     * 图片中添加背景水印并输出到指定流
     * 
     * @param data
     * @param out
     * @param channelName
     * @return
     * @throws Exception
     */
    public static boolean createBgMark(byte[] data, FileOutputStream out, String channelName) throws Exception {
        int i = (int) (bgImgs.size() * Math.random());
        return createMark(data, out, (Image) bgImgs.get(i), false);
    }

    /** */
    /**
     * 生成随机水印并输出到指定流
     * 
     * @param data
     * @param out
     * @return
     * @throws Exception
     */
    public static boolean createRandomMark(byte[] data, FileOutputStream out) throws Exception {
        int i = 0;
        Image temImg = null;
        if (!flag) {
            i = (int) (logoImgs.size() * Math.random());
            temImg = (Image) logoImgs.get(i);
        }
        else {
            i = (int) (bgImgs.size() * Math.random());
            temImg = (Image) bgImgs.get(i);
        }
        flag = !flag;
        return createMark(data, out, temImg, flag);
    }

    /** */
    /**
     * 生成水印并输出到指定流
     * 
     * @param data
     * @param out
     * @param waterImg
     *            水印图片的类型（背景或图标），应与isLogoImg参数一致
     * @param isLogoImg
     *            等于true 时生成图标水印，否则为背景水印
     * @return
     * @throws Exception
     */
    private static boolean createMark(byte[] data, FileOutputStream out, Image waterImg,
            boolean isLogoImg) throws Exception {
        ImageIcon imgIcon = new ImageIcon(data);
        Image theImg = imgIcon.getImage();

        int width = theImg.getWidth(null);
        int height = theImg.getHeight(null);
        if (width < 200 || height < 200) {// 小图片不加水印真接输入,如头像图片
            BufferedOutputStream fout = null;
            ByteArrayInputStream in = new ByteArrayInputStream(data);
            try {
                byte[] b = new byte[1024 * 10];
                fout = new BufferedOutputStream(out);
                while (in.read(b) > 0) {
                    out.write(b);
                }
                out.flush();
                out.close();
                in.close();
            }
            catch (Exception e) {
                e.printStackTrace();
                throw e;
            }
            finally {
                if (in != null) {
                    in.close();
                }
                if (fout != null) {
                    fout.close();
                }
            }
            return true;
        }

        BufferedImage bimage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics2D g = bimage.createGraphics();
        g.setBackground(Color.white);
        g.drawImage(theImg, 0, 0, null);

        if (isLogoImg) {// 生成图标水印
            // 设置图片透明度
            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.4f));
            g.drawImage(waterImg, width - waterImg.getWidth(null), height
                    - waterImg.getHeight(null), null);
        }
        else {// 生成背景水印
            // '0.2f'设置字体透明度
            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.3f));
            int w = waterImg.getWidth(null);
            int h = waterImg.getHeight(null);
            if (width > w && height > h) {
                int sw = (width % w) / (width / w + 1);// 填充水印图片横向间距
                int sh = (height % h) / (height / h + 1);// 填充水印图片纵向间距
                for (int i = sw; i + w + sw <= width; i += w + sw) {
                    for (int j = sh; j + h + sh <= height; j += h + sh) {
                        g.drawImage(waterImg, i, j, null);
                    }
                }
            }
            else {// 若上传的图片尺寸小于背景水印图片的尺寸则采用图标水印
                if (logoImgs != null && logoImgs.size() > 0) {
                    Image img = (Image) logoImgs.get(0);
                    // 设置图片透明度
                    g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.4f));
                    g
                            .drawImage(img, width - img.getWidth(null), height
                                    - img.getHeight(null), null);
                }
            }
        }
        g.dispose();

        try {
            JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
            JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(bimage);
            param.setQuality(80f, true);
            encoder.encode(bimage);
        }
        catch (Exception e) {
            throw e;
        }
        finally {
            if (out != null) {
                out.close();
            }
        }
        return true;
    }

    public static void main(String[] args) {
        ArrayList logoImgUrls = new ArrayList();
        for (int i = 1; i <= 24; i++) {
            if (i < 10)
                logoImgUrls.add("0" + i + ".png");
            else
                logoImgUrls.add(i + ".png");
        }
        WaterMark.setLogoImgs(logoImgUrls, "d:/2008奥运吉祥物图标/");
        
        ArrayList bgImgUrls = new ArrayList();
        for (int i = 1; i <= 8; i++) {
            bgImgUrls.add(i + ".jpg");
        }
        WaterMark.setBgImgs(bgImgUrls, "d:/月亮背景图片/");
        
        try {
            WaterMark.createLogoMark(FileUtil.fileToStream(new File("d:/ddd.jpg")), new FileOutputStream("d:/sss.jpg"), "");
            //WaterMark.createBgMark(FileUtil.fileToStream(new File("d:/ddd.jpg")), new FileOutputStream("d:/sss.jpg"), "");
        }
        catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }
}
